from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_apscheduler import APScheduler
from config import Config
import redis
import pymysql
import logging

pymysql.install_as_MySQLdb()

db = SQLAlchemy()
migrate = Migrate()
apscheduler = APScheduler()
redis_client = None

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)


def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)

    db.init_app(app)
    migrate.init_app(app, db)

    global redis_client
    redis_client = redis.Redis(
        host=app.config["REDIS_HOST"],
        port=app.config["REDIS_PORT"],
        db=app.config["REDIS_DB"],
    )

    from . import views, views_page
    # models和scheduler模块在当前应用初始化中不需要显式导入
    # 如果后期需要在应用启动时初始化这些模块，请取消下面的注释
    # from . import models, scheduler

    views.init_app(app)
    views_page.init_app(app)

    # 初始化APScheduler
    init_scheduler(app)

    return app


def init_scheduler(app):
    """初始化定时任务调度器

    Args:
        app: Flask应用实例
    """
    from config_params import three_shift_params

    # 配置APScheduler
    apscheduler.init_app(app)
    apscheduler.api_enabled = False  # 禁用API接口

    # 检查是否启用自动排班
    auto_schedule_enabled = three_shift_params.get("auto_schedule_enabled", False)
    auto_schedule_immediate = three_shift_params.get("auto_schedule_immediate", True)

    # 导入自动排班函数
    from .three_shift import auto_schedule

    # 创建一个包装函数，传入app参数
    def scheduled_auto_schedule():
        with app.app_context():
            auto_schedule()

    if auto_schedule_enabled:
        # 获取自动排班间隔分钟数
        auto_schedule_minutes = three_shift_params.get("auto_schedule_minutes", 7)

        # 添加自动排班任务
        apscheduler.add_job(
            id="auto_schedule_job",
            func=scheduled_auto_schedule,
            trigger="interval",
            minutes=auto_schedule_minutes,
            replace_existing=True,
        )

        # 启动调度器
        apscheduler.start()
        logging.info(f"自动排班功能已启用，间隔 {auto_schedule_minutes} 分钟")

        # 如果配置了立即执行，则立即执行一次排班
        if auto_schedule_immediate:
            logging.info("立即执行一次自动排班...")
            scheduled_auto_schedule()
            logging.info("立即执行自动排班完成")
    else:
        logging.info("自动排班功能未启用")
